﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using System.Threading.Tasks;

namespace throneOfGames.Models
{
    public class GameHub : Hub
    {
        public void Join(string groupId)
        {
            Groups.Add(Context.ConnectionId, groupId);
        }

        public void ClickCell(string groupName, string cellId)
        {
            Clients.OthersInGroup(groupName).cellClicked(cellId);
        }

        public void DeclareWinner(string groupName, string name, string message)
        {
            Clients.OthersInGroup(groupName).winnerDeclared(name, message);
        }

        public void Send(string groupName, string name, string message)
        {
            Clients.OthersInGroup(groupName).addNewMessageToPage(name, message);
        }

        public void ChangeInside(string groupName, string name, string id)
        {
            throneOfGamesDataContext db = new throneOfGamesDataContext();
            int pId = 0;
            int groupId = 0;
            int.TryParse(id, out pId);
            int.TryParse(groupName, out groupId);
            var inside = (from p in db.Players
                          where p.ID == pId
                          && p.gameID == groupId
                          select p).SingleOrDefault();
            var player = (from p in db.Players
                          where p.User.userName == name
                          && p.gameID == groupId
                          select p).SingleOrDefault();
            db.toggleInside(inside.ID, true);
            db.toggleInside(player.ID, false);
        }

        public void AttackTokyo(string groupName, string name, string id, string attacks)
        {
            throneOfGamesDataContext db = new throneOfGamesDataContext();
            int pId = 0;
            string attack = " ";
            int.TryParse(id, out pId);
            var isInside = (from p in db.Players
                         join u in db.Users
                         on p.userID equals u.ID
                         where p.isInside == true
                         select p).SingleOrDefault();
            if (isInside == null)
            {
                db.toggleInside(pId, false);
                db.SubmitChanges();
            }
            else
            {
                string player = isInside.User.userName;
                if (isInside.User.userName == name)
                {
                    attack = "all";
                    Clients.OthersInGroup(groupName).getAttack(name, player, attack, attacks);
                }
                else
                {
                    attack = "tokyo";
                    Clients.OthersInGroup(groupName).getAttack(name, player, attack, attacks);
                }

            }

        }

        public string IsItMyTurn(string groupName, string name)
        {
            throneOfGamesDataContext db = new throneOfGamesDataContext();
            var query = (from p in db.Players
                          join u in db.Users
                          on p.userID equals u.ID
                          where u.userName == name
                          join g in db.Games
                          on p.gameID equals g.ID
                          where p.playerNumber == g.currentPlayer
                         select p).FirstOrDefault();
            if (query != null)
            {
                return "true";
            }
            else
            {
                return "false";
            }
    }

        public void UpdateTurn(string groupName)
        {
            throneOfGamesDataContext db = new throneOfGamesDataContext();
            int groupNumber = 0;
            int.TryParse(groupName,out groupNumber);
            var maxPlayers = (from g in db.Games
                              where g.ID == groupNumber
                              select g).FirstOrDefault();
            if (maxPlayers.currentPlayer == maxPlayers.maxPlayersOfGame)
            {
                db.updateCurrPlayer(groupNumber, 1);
            }
            else if (maxPlayers.currentPlayer > maxPlayers.maxPlayersOfGame)
            {
                if (maxPlayers.maxPlayersOfGame > 1)
                {
                    db.updateCurrPlayer(groupNumber, maxPlayers.currentPlayer - 1);
                }
            }
            else
            {
                db.updateCurrPlayer(groupNumber, maxPlayers.currentPlayer + 1);
            }        
        }

        public void UpdatePlayer(string groupName, string id, string playerName, string health, string energy, string points)
        {
            throneOfGamesDataContext db = new throneOfGamesDataContext();
            
            int pId, pHealth, pEnergy, pPoints = 0;
            int.TryParse(id, out pId);
            int.TryParse(health, out pHealth);
            int.TryParse(energy, out pEnergy);
            int.TryParse(points, out pPoints);
            db.updatePlayerStats(pId, pHealth, pPoints, pEnergy);
            db.SubmitChanges();
        }
        public void SendUpdatedPlayer(string groupName, string playerName, string health, string energy, string points, string attack)
        {
            Clients.OthersInGroup(groupName).playerUpdate(playerName, health, energy, points, attack);
        }
        public bool AllDead(string groupName, string name)
        {
            throneOfGamesDataContext db = new throneOfGamesDataContext();
            int groupNumber = 0;
            int.TryParse(groupName,out groupNumber);
            var playersLeft = (from p in db.Players
                               join g in db.Games
                               on p.gameID equals g.ID
                               where g.maxPlayersOfGame == 1
                               && g.ID == groupNumber
                               select p).SingleOrDefault();
            if (playersLeft != null && playersLeft.User.userName == name)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public void PlayerDead(string groupName, string playerName)
        {
            throneOfGamesDataContext db = new throneOfGamesDataContext();
            int groupNumber = 0;
            int.TryParse(groupName,out groupNumber);
            var deadPlayer = (from p in db.Players
                              where p.User.userName == playerName
                              select p).SingleOrDefault();
            var playersLeft = (from p in db.Players
                               where p.playerNumber > deadPlayer.playerNumber
                               && p.gameID == groupNumber
                               select p);
            foreach (var p in playersLeft)
            {
                if (p.playerNumber > 1)
                {
                    p.playerNumber -= 1;
                    db.SubmitChanges();
                }
                
            }
            var currGame = (from g in db.Games
                            where g.ID == groupNumber
                            select g).SingleOrDefault();
            if (currGame.maxPlayersOfGame > 1)
            {
                currGame.maxPlayersOfGame -= 1;
            }
            if (currGame.currentPlayer == deadPlayer.playerNumber)
            {
                if (currGame.maxPlayersOfGame == deadPlayer.playerNumber)
                {
                    currGame.currentPlayer = 1;
                }
            }
            deadPlayer.isInside = false;
            deadPlayer.playerNumber = 0;
            db.SubmitChanges();
        }
    }
}